package com.dl698.asn1.axdr;

import com.dl698.util.ReverseByteArrayInputStream;
import com.dl698.util.ReverseByteArrayOutputStream;

import java.io.IOException;

/**
 * AXDR位串类型
 * 实现位串数据的编解码
 * 
 * @author wind
 * @version 1.1.1
 */
public class AxdrBitString implements AxdrType {

    private byte[] bitString = null;
    private int numBits = 0;
    private boolean fixedLength = false;

    /**
     * 默认构造函数
     */
    public AxdrBitString() {
    }

    /**
     * 设置位数
     * 
     * @param numBits 位数
     */
    public void setNumBit(int numBits) {
        this.numBits = numBits;
        this.fixedLength = true;
    }

    /**
     * 设置位串值
     * 
     * @param value 位串值
     */
    public void setBitString(byte[] value) {
        this.bitString = value;
        this.fixedLength = true;
    }

    @Override
    public int encode(ReverseByteArrayOutputStream output) {
        try {
            if (bitString == null) {
                throw new RuntimeException("bitString is null");
            } else {
                int codeLength = bitString.length;
                for (int i = bitString.length - 1; i >= 0; --i) {
                    output.write(bitString[i]);
                }
                if (!fixedLength) {
                    AxdrLength length = new AxdrLength(numBits);
                    codeLength += length.encode(output);
                }
                return codeLength;
            }
        } catch (IOException e) {
            throw new RuntimeException("Encode error", e);
        }
    }

    @Override
    public int decode(ReverseByteArrayInputStream input) {
        try {
            int codeLength = 0;
            if (!fixedLength) {
                AxdrLength l = new AxdrLength(0);
                codeLength += l.decode(input);
                numBits = l.getValue();
            }

            int byteArrayLength = numBits % 8 == 0 ? numBits / 8 : numBits / 8 + 1;
            codeLength += byteArrayLength;
            bitString = new byte[byteArrayLength];

            if (byteArrayLength != 0 && input.readOffset(bitString, 0, byteArrayLength) < byteArrayLength) {
                throw new RuntimeException("Error Decoding AxdrBitString");
            }

            return codeLength;
        } catch (IOException e) {
            throw new RuntimeException("Decode error", e);
        }
    }

    /**
     * 获取值
     * 
     * @return 位串值
     */
    public byte[] getValue() {
        if (bitString == null) {
            throw new RuntimeException("bitString is null");
        } else {
            return bitString;
        }
    }

    /**
     * 获取位数
     * 
     * @return 位数
     */
    public int getNumBits() {
        return numBits;
    }

    /**
     * 是否为固定长度
     * 
     * @return true如果为固定长度
     */
    public boolean isFixedLength() {
        return fixedLength;
    }

    /**
     * 获取数据编码
     * 
     * @return 数据编码
     */
    public byte[] getDataCode() {
        return bitString;
    }

    @Override
    public String toString() {
        if (bitString == null) {
            return "bitString is null";
        } else {
            StringBuilder s = new StringBuilder();
            for (int i = 0; i < numBits; i++) {
                if (((bitString[i / 8] & 0xFF) & (0x80 >> (i % 8))) == (0x80 >> (i % 8))) {
                    s.append('1');
                } else {
                    s.append('0');
                }
            }
            return s.toString();
        }
    }
}